package org.example.controller;


import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.models.auth.In;
import org.example.aop.Log;
import org.example.config.SystemInfo;
import org.example.entity.*;
import org.example.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static org.bouncycastle.asn1.x500.style.RFC4519Style.l;
import static org.bouncycastle.asn1.x500.style.RFC4519Style.o;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author zhaowenting
 * @since 2024-03-21
 */
@RestController
@RequestMapping("/tb-user")
public class TbUserController {
    @Autowired
    ISysTypeService iSysTypeService;
    /*字典*/
    @Autowired
    ISysDictionaryService iSysDictionaryService;
    @Autowired
    IUserRoleCenterService iUserRoleCenterService;
    @Autowired
    ITbHobbyService iTbHobbyService;
    /*地址*/
    @Autowired
    IDistrictService iDistrictService;
    @Autowired
    ITbUserService iTbUserService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    ITbPostService iTbPostService;
    @Autowired
    IRoleMenuService iRoleMenuService;
    @Autowired
    ITbRoleService iTbRoleService;
    /*注册用户*/
    @RequestMapping("addLogin")
    public String add(@RequestBody Map tbUser){
        System.out.println("www====="+tbUser);
        List<Integer> postsList = (List<Integer>) tbUser.get("posts");
        StringBuilder posts = new StringBuilder();
        for (Integer id : postsList) {
            TbPost tbPost = iTbPostService.getById(id);
            posts.append(tbPost.getName()+",");
        }
        String ps = posts.substring(0, posts.lastIndexOf(","));
        System.out.println("岗位====ps====="+ps);
        TbUser dbUser = BeanUtil.copyProperties(tbUser, TbUser.class);
        StringBuilder addr = new StringBuilder();
        StringBuilder hobbyId = new StringBuilder();
        List<String> addrlist = (List<String>) tbUser.get("addr");
        List<Integer> o = (List<Integer>) tbUser.get("hobbyId");
        for (Integer id : o) {
            TbHobby byId = iTbHobbyService.getById(id);
            hobbyId.append(byId.getName() + ",");
        }
        System.out.println("hobbyId====="+hobbyId);
        for (String s : addrlist) {
            addr.append(s);
        }
        System.out.println("地址："+addr);
        LambdaQueryWrapper<TbUser> tbUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbUserLambdaQueryWrapper.eq(TbUser::getUsername,dbUser.getUsername());
        TbUser dbuser = iTbUserService.getOne(tbUserLambdaQueryWrapper);
        if(dbuser!=null){
            System.out.println("该账号已存在");
            return "error";
        }
        String salt = RandomUtil.randomString(4);
        String password = DigestUtil.md5Hex(dbUser.getPassword() + salt);
        dbUser.setState(1);
        String substring = hobbyId.substring(0,hobbyId.lastIndexOf(","));
        System.out.println("0--------"+substring);
        dbUser.setHobbyId(substring+"");
        dbUser.setAddr(addr+"");
        dbUser.setSalt(salt);
        dbUser.setPosts(ps);
        dbUser.setPassword(password);
        System.out.println("iiiii======"+dbUser);
        dbUser.setCreateTime(new Date());
        iTbUserService.save(dbUser);
        LambdaQueryWrapper<UserRoleCenter> userRoleCenterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userRoleCenterLambdaQueryWrapper.eq(UserRoleCenter::getUserId,dbUser.getId());
        List<UserRoleCenter> list = iUserRoleCenterService.list(userRoleCenterLambdaQueryWrapper);
        if(CollectionUtil.isEmpty(list)){
            UserRoleCenter userRoleCenter = new UserRoleCenter();
            userRoleCenter.setUserId(dbUser.getId());
            userRoleCenter.setRoleId(2);
            iUserRoleCenterService.save(userRoleCenter);
        }
        return "success";
    }
    /*上传图片*/
    @RequestMapping("upload")
    public String upload(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."), originalFilename.length());
        System.out.println("图片后缀名：======="+substring);
        String filename=UUID.randomUUID()+substring;
        file.transferTo(new File("/Users/zhaowenting/Desktop/upload/pic/"+filename));
        return "http://172.20.10.5:8081/goods/upload/pic/"+filename;
    }
    @RequestMapping("districtList")
    public void districtList(){
        final List<TbDistrict> list = iDistrictService.list();
        final ArrayList<TbDistrict> tbDistricts = new ArrayList<>();
        for (TbDistrict district : list) {
            if(district.getPid()==0){
                tbDistricts.add(district);
            }
        }
        for (TbDistrict tbDistrict : tbDistricts) {
            childrenList(tbDistrict.getId(),tbDistricts);
        }
        System.out.println(JSONUtil.toJsonStr(tbDistricts));
    }

    /**
     *
     * @param id
     * @param districtList
     * @return
     */
    public List<TbDistrict> childrenList(Integer id, List<TbDistrict> districtList){
        final ArrayList<TbDistrict> chidrenList = new ArrayList<>();
        for (TbDistrict tbDistrict : districtList) {
            if(tbDistrict.getPid()==id){
                chidrenList.add(tbDistrict);
            }
        }
        for (TbDistrict tbDistrict : chidrenList) {
            childrenList(tbDistrict.getId(),chidrenList);
        }
        if(CollUtil.isEmpty(chidrenList)){
            return new ArrayList<>();
        }
        return chidrenList;
    }

    /**
     * tree树形方法
     * @return
     */
    @RequestMapping("districtList2")
    public List<Tree<String>> districtList2(){
        final List<TbDistrict> list = iDistrictService.list();
//配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都有默认值的
        treeNodeConfig.setIdKey("id");
        treeNodeConfig.setNameKey("name");
        treeNodeConfig.setParentIdKey("pid");
// 最大递归深度
        treeNodeConfig.setDeep(3);

//转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.build(list, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(treeNode.getId()+"");
                    tree.setParentId(treeNode.getPid()+"");
                    tree.setName(treeNode.getName());
                    // 扩展属性 ...
                });
        return treeNodes;
    }

    /**
     * 登录方法
     * @param tbUser
     * @return
     */
    @Log
    @RequestMapping("login")
    public Map login(@RequestBody TbUser tbUser){
        HashMap map1 = new HashMap<>();
        LambdaQueryWrapper<TbUser> tbUserLambdaQueryWrapper = new LambdaQueryWrapper<>();
        tbUserLambdaQueryWrapper.eq(TbUser::getUsername,tbUser.getUsername());
        TbUser dbuser = iTbUserService.getOne(tbUserLambdaQueryWrapper);
        if(dbuser==null){
            map1.put("msg","不存在此账号");
            return map1;
        }
        String uuid = (String) redisTemplate.opsForValue().get(tbUser.getUuid() + "");
        if(!StrUtil.equalsIgnoreCase(uuid,tbUser.getCode())){
            map1.put("msg","验证码错误");
            return map1;
        }
        if(dbuser.getState()==2){
            map1.put("msg","该账号已被锁定");
            return map1;
        }
        final String md5Hex = DigestUtil.md5Hex(tbUser.getPassword() + dbuser.getSalt());
        if(!StrUtil.equalsIgnoreCase(md5Hex,dbuser.getPassword())){
            String key="error"+dbuser.getId();
            if(redisTemplate.hasKey(key)){
                Long expire = redisTemplate.getExpire(key);
                String count = redisTemplate.opsForValue().get(key) + "";
                redisTemplate.opsForValue().set(key,Integer.parseInt(count)+1,expire,TimeUnit.SECONDS);
            }
            else{
                redisTemplate.opsForValue().set(key,1,60, TimeUnit.SECONDS);
            }
            final String num = redisTemplate.opsForValue().get(key) + "";
            if(Integer.parseInt(num)>=3){
                dbuser.setState(2);
                iTbUserService.updateById(dbuser);
                map1.put("msg","密码错误三次该账号已被锁定");
                return map1;
            }
            else {
                map1.put("msg","密码错误");
                return map1;
            }
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("dbuser",dbuser);
        final String token = JWTUtil.createToken(map, "123".getBytes());
        map1.put("userId",dbuser.getId());
        map1.put("token",token);
        map1.put("msg","success");
        map1.put("roleId",dbuser.getRoleId());
        map1.put("name",dbuser.getUsername());
        System.out.println("roleId=========="+dbuser.getRoleId());
        redisTemplate.opsForValue().set("userId",dbuser.getId());
        redisTemplate.opsForValue().set("username",dbuser.getUsername());
        redisTemplate.opsForValue().set("tokenId",token);
        return map1;
    }
//    验证码

    /**
     * 获取验证码
     * @param uuid
     * @param response
     * @throws IOException
     */
    @RequestMapping("getCode")
    public void getCode(String uuid, HttpServletResponse response) throws IOException {
        System.out.println("===uuid====="+uuid);
        // 自定义纯数字的验证码（随机4位数字，可重复）
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        lineCaptcha.setGenerator(randomGenerator);
// 重新生成code
        lineCaptcha.write(response.getOutputStream());
        redisTemplate.opsForValue().set(uuid,lineCaptcha.getCode(),5,TimeUnit.MINUTES);

    }

    /**
     * 用户列表
     * @return
     */
    @Log
    @RequestMapping("userList")
    public List<TbUser> userList(){
        final List<TbUser> list = iTbUserService.listd();
        return list;
    }

    /**
     * 根据id改变 修改del_id为2 软删除
     * @param id
     * @return
     */
    @RequestMapping("handleDelete")
    public String handleDelete(Integer id){
        TbUser tbUser = iTbUserService.getById(id);
        tbUser.setDelId(2);
        iTbUserService.updateById(tbUser);
        return "success";
    }

    /**
     * 根据id获取用户信息
     * @param id
     * @return
     */
    @RequestMapping("getByIdUser")
    public TbUser getByIdUser(Integer id){
        TbUser tbUser = iTbUserService.getById(id);
        return tbUser;
    }

    @RequestMapping("roleCheckList")
    public ArrayList<TbPost> roleCheckList(Integer id){
        LambdaQueryWrapper<UserRoleCenter> userRoleCenterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userRoleCenterLambdaQueryWrapper.eq(UserRoleCenter::getUserId,id);
        List<UserRoleCenter> list = iUserRoleCenterService.list(userRoleCenterLambdaQueryWrapper);
        ArrayList<TbPost> tbRoles = new ArrayList<>();
        for (UserRoleCenter userRoleCenter : list) {
            TbPost byId = iTbPostService.getById(userRoleCenter.getRoleId());
            tbRoles.add(byId);
        }
        return tbRoles;
    }
    @RequestMapping("updateState")
    public String updateState(Integer id){
        TbUser tbUser = iTbUserService.getById(id);
        tbUser.setState(2);
        iTbUserService.updateById(tbUser);
        return "success";
    }

    /**
     * 修改用户
     * 用户管理
     */
    @RequestMapping("updateUser")
    public String updateUser(@RequestBody Map tbUser) {
        System.out.println("修改用户信息为===="+tbUser);
        String posts = (String) tbUser.get("posts");
        System.out.println("获取到的岗位Id为==="+posts);
        final String[] split = posts.split(",");
        /**
         * 将posts分割成数组 放到set集合当中
         */
        HashSet<String> postsGather = new HashSet<>(Arrays.asList(split));
        StringBuilder stringBuilder = new StringBuilder();
        /**
         * set结合转换成数组
         */
        String[] array = postsGather.toArray(new String[0]);
        for (String id : array) {
            System.out.println("转换后的岗位id==="+id);
            TbPost byId = iTbPostService.getById(id);
            stringBuilder.append(byId.getName()+",");
        }
        System.out.println("数组的长度为：==="+array.length);
        String substring = stringBuilder.substring(0, stringBuilder.lastIndexOf(","));
        TbUser newUser = BeanUtil.copyProperties(tbUser, TbUser.class);
        newUser.setPosts(substring);
        newUser.setRoleId(newUser.getRoleId());
        iTbUserService.updateById(newUser);
        Integer roleId = newUser.getRoleId();
        System.out.println("角色id:=="+roleId);
        if (roleId!=null){
            LambdaQueryWrapper<UserRoleCenter> userRoleCenterLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userRoleCenterLambdaQueryWrapper.eq(UserRoleCenter::getUserId,newUser.getId());
            UserRoleCenter dbUserRole = iUserRoleCenterService.getOne(userRoleCenterLambdaQueryWrapper);
            dbUserRole.setRoleId(newUser.getRoleId());
            iUserRoleCenterService.updateById(dbUserRole);
        }
        return "success";
    }

    /**
     * 获取性别
     * @return
     */
    @RequestMapping("sexList")
    public Object sexList(){
        LambdaQueryWrapper<SysDictionary> sysTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysTypeLambdaQueryWrapper.eq(SysDictionary::getSysType,"tb_user_sex");
        final List<SysDictionary> list = iSysDictionaryService.list(sysTypeLambdaQueryWrapper);
        return list;
    }
    /**
     * 字典类型列表
     */
    @RequestMapping("dictionaryTypeLisr")
    public List<SysType> dictionaryTypeLisr(){
        Boolean b = redisTemplate.hasKey("dictionaryTypeLisr");
        if(b){
            List dictionaryTypeLisr = redisTemplate.opsForList().range("dictionaryTypeLisr", 0, -1);
            return dictionaryTypeLisr;
        }
        //先查询字典类型表里的数据
        List<SysType> list = iSysTypeService.list();
        //判断字典类型表是否为空
        if(CollectionUtil.isNotEmpty(list)){
            for (SysType sysType : list) {
                //查询字典类型表里的数据
                LambdaQueryWrapper<SysDictionary> sysTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
                sysTypeLambdaQueryWrapper.eq(SysDictionary::getSysType,sysType.getSysType());
                //查询字典表里的数据
                List<SysDictionary> sysDictionaries = iSysDictionaryService.list(sysTypeLambdaQueryWrapper);
                sysType.setDictionaries(sysDictionaries);
            }
        }
        redisTemplate.opsForList().rightPushAll("dictionaryTypeLisr",list);
        return list;
    }

    /**
     * 字典列表
     * @return
     */
    @Log
    @RequestMapping("dictionaryList")
    public List<SysDictionary> dictionaryList(String sysType){
        System.out.println("前端传过来的字典的类型："+sysType);
        LambdaQueryWrapper<SysDictionary> sysDictionaryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDictionaryLambdaQueryWrapper.eq(SysDictionary::getSysType,sysType);
        List<SysDictionary> list = iSysDictionaryService.list(sysDictionaryLambdaQueryWrapper);
        return list;
    }
    /*
    * 根据id删除字典表的类型
    * */
    @RequestMapping("deleteDictType")
    public String deleteDictType(Integer id){
        iSysTypeService.removeById(id);
        redisTemplate.delete("dictionaryTypeLisr");
        return "success";
    }

    /**
     * 单选框
     * 字典类型状态
     * @return
     */

    @RequestMapping("dictStateTypeList")
    public Object dictStateTypeList(){
        LambdaQueryWrapper<SysDictionary> sysDictionaryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDictionaryLambdaQueryWrapper.eq(SysDictionary::getSysType,"sys_dictionary_state");
        final List<SysDictionary> list = iSysDictionaryService.list(sysDictionaryLambdaQueryWrapper);
        return list;
    }
    //添加或修改字典类型
    @RequestMapping("saveOrUpdateDictType")
    public String addDictType(@RequestBody SysType sysType){
        if(sysType.getId()==null){
            LambdaQueryWrapper<SysType> sysTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysTypeLambdaQueryWrapper.eq(SysType::getSysType,sysType.getSysType());
            SysType one = iSysTypeService.getOne(sysTypeLambdaQueryWrapper);
            if(one!=null){
                return "error";
            }
        }
        System.out.println("数据：======"+sysType);
        sysType.setCreateTime(new Date());
        iSysTypeService.saveOrUpdate(sysType);
        //根据字典类型标识查询
        LambdaQueryWrapper<SysDictionary> sysDictionaryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysDictionaryLambdaQueryWrapper.eq(SysDictionary::getTypeId,sysType.getId());
        List<SysDictionary> list = iSysDictionaryService.list(sysDictionaryLambdaQueryWrapper);
        if(CollectionUtil.isNotEmpty(list)){
            for (SysDictionary sysDictionary : list) {
                sysDictionary.setSysType(sysType.getSysType());
                sysDictionary.setState(sysType.getState());
                iSysDictionaryService.updateById(sysDictionary);
            }
        }
        redisTemplate.delete("dictionaryTypeLisr");
        return "success";
    }
    /**
     * 根据id查询字典类型里的数据
     */
    @RequestMapping("getByIdDictType")
    public SysType getByIdDictType(Integer id){
        SysType sysType = iSysTypeService.getById(id);
        return sysType;
    }

    /**
     * 添加字典表
     * @param sysDictionary
     * @return
     */
    @RequestMapping("addDict")
    public String addDict(@RequestBody SysDictionary sysDictionary){
        System.out.println("前端传过来的字典表数据====="+sysDictionary);
        //根据前端传过来的typeId查寻字典类型表获取sysType
        SysType sysType = iSysTypeService.getById(sysDictionary.getTypeId());
        sysDictionary.setSysType(sysType.getSysType());
        sysDictionary.setState(1);
        iSysDictionaryService.save(sysDictionary);
        return "success";
    }
    /**
     * 根据id删除字典表
     */
    @RequestMapping("deleteDict")
    public String deleteDict(Integer id){
        iSysDictionaryService.removeById(id);
        return "success";
    }

    /**
     * 修改字典表中的数据
     */
    @RequestMapping("updateDict")
    public String updateDict(@RequestBody SysDictionary sysDictionary){
        iSysDictionaryService.updateById(sysDictionary);
        return "success";
    }
    @RequestMapping("supervisoryControl")
    public Map supervisoryControl() throws UnknownHostException {
        HashMap map = new HashMap<>();
        SystemInfo systemInfo = new SystemInfo();
        //获取cup的使用情况
        double cpuUsage = systemInfo.getCPUUsage();
        System.err.println("获取cup的使用情况:"+cpuUsage);
        //获取系统内存使用情况
        double memoryUsage = systemInfo.getMemoryUsage();
        System.err.println("获取系统内存使用情况:"+memoryUsage);
        //获取Jvm的使用情况
        double jvmUsage = systemInfo.getJVMUsage();
        System.err.println("获取Jvm的使用情况:"+jvmUsage);
        //获取cpu核心数
        int cpuNum = Runtime.getRuntime().availableProcessors();
        System.err.println("获取cup核心数:"+cpuNum);
        //获取主机信息
        InetAddress inetAddress = InetAddress.getLocalHost();
        System.err.println("主机名："+inetAddress.getHostName());
        System.out.println("ip地址："+inetAddress.getHostAddress());
        map.put("cpuUsage",cpuUsage);
        map.put("memoryUsage",memoryUsage);
        map.put("jvmUsage",jvmUsage);
        map.put("cpuNum",cpuNum);
        map.put("hostName",inetAddress.getHostName());
        map.put("ipAddr",inetAddress.getHostAddress());
        return map;
    }

}
